﻿#include"MainModel.h"
#include"InventoryModel.h"
#include"ProductModel.h"
#include"OrderModel.h"
//表名
#define USERTABLENAME "User"
#define INVENTORYTABLENAME "Inventory"
#define PRODUCTTABLENAME "Product"
#define ORDERTABLENAME "Order"
MainModel::MainModel()
{
}

bool MainModel::modifyUserInfoMySql(const XQUserData& user)
{
	auto mysql = this->mysql();
	//auto data = mysql->findData(TABLENAME, "uuid", "`account`=?", { user.account() });
	if (!mysql->findData(USERTABLENAME, "uuid", "`account`=?", { user.account()}).isEmpty())
	{
		auto u = user;
		u.setMTime(QDateTime::currentDateTime());
		if (mysql->UPDATE(USERTABLENAME, u.toMap(u.fields()), "`account`=?", { QString("%1").arg(u.account()) }))
			return true;
	}
	return false;
}

QList<XQUserData> MainModel::userListMySql()
{
	QList<XQUserData> list;
	auto mysql = this->mysql();
	auto datas=mysql->findDatas(USERTABLENAME,XQUserData::Fields());
	for (auto& data:datas)
	{
		list << XQUserData(data,false);
	}
	return list;
}

bool MainModel::registerAccountMySql(const XQUserData& user, XQUserData* newUser)
{
	auto mysql = this->mysql();
	if (mysql->findData(USERTABLENAME, "uuid", "`account`=?", { QString("%1").arg(user.account()) }).isEmpty())
	{
		XQUserData u = user;
		u.setUuid(mysql->uuid());
		u.setPermission(XQUserData::Permission::user);
		u.setMTime();
		u.setCTime();
		if (mysql->INSERT(USERTABLENAME, u.toMap(u.fields())))
		{
			if (newUser)
				*newUser = u;
			return true;
		}
	}
	return false;
}

bool MainModel::removeUserMySql(const XQUserData& user)
{
	auto mysql = this->mysql();
	if (!mysql->findData(USERTABLENAME, "uuid", "`account`=?", { QString("%1").arg(user.account()) }).isEmpty())
	{
		if (mysql->DELETE(USERTABLENAME, "`account`=?", { QString("%1").arg(user.account()) }))
		{
			return true;
		}
	}
	return false;
}


quint64 MainModel::newInventoryIDMySql()
{
	auto mysql = this->mysql();
	mysql->Query(QString("SHOW TABLE STATUS LIKE  '%1'").arg(INVENTORYTABLENAME));
	//QVariantList data;
	return mysql->result_all()[0][10].toULongLong();
}

bool MainModel::addInventoryMySql(const InventoryModel& inventory, InventoryModel* newInventory)
{
	auto mysql = this->mysql();
	if (mysql->findData(INVENTORYTABLENAME, "id", "`name`=?", { QString("%1").arg(inventory.name()) }).isEmpty())
	{
		auto fields = inventory.fields();
		if (mysql->INSERT(INVENTORYTABLENAME, inventory.toMap(fields)))
		{
			return true;
		}

	}

	return false;
}

bool MainModel::modifyInventoryMySql(const InventoryModel& inventory)
{
	auto mysql = this->mysql();
	if (!mysql->findData(INVENTORYTABLENAME, "name", "`id`=?", { inventory.inventory_id() }).isEmpty())
	{
		auto u = inventory;
		u.setMTime(QDateTime::currentDateTime());
		if (mysql->UPDATE(INVENTORYTABLENAME, u.toMap(u.fields()), "`id`=?", { QString("%1").arg(u.inventory_id()) }))
			return true;
	}
	return false;
}

bool MainModel::removeInventoryMySql(const InventoryModel& inventory)
{

	auto mysql = this->mysql();
	if (!mysql->findData(INVENTORYTABLENAME, "name", "`id`=?", { QString("%1").arg(inventory.inventory_id()) }).isEmpty())
	{
		if (mysql->DELETE(INVENTORYTABLENAME, "`id`=?", { QString("%1").arg(inventory.inventory_id()) }))
		{
			return true;
		}
	}
	return false;
}

QList<InventoryModel> MainModel::InventoryListMySql()
{
	QList<InventoryModel> list;
	auto mysql = this->mysql();
	;
	for (auto&data: mysql->findDataAll_toMap(INVENTORYTABLENAME))
	{
		list << InventoryModel(data);
	}
	return list;
}

QList<QString> MainModel::InventoryTypeList()
{
	auto mysql = this->mysql();
	if (mysql->Query(QString("SELECT DISTINCT `type` FROM `%1`; ").arg(INVENTORYTABLENAME)))
	{
		auto data = mysql->result_all();
		QList<QString> list;
		for (auto&d:data)
		{
			list << d[0].toString();
		}
		return list;
	}
	return QList<QString>();
}

QList<QString> MainModel::InventoryNameList()
{
	auto mysql = this->mysql();
	auto data = mysql->findData(INVENTORYTABLENAME,"name");
	QList<QString> list;
	for (auto& d : data)
	{
		list << d.toString();
	}
	return list;
	return QList<QString>();
}

QString MainModel::InventoryType(const QString& name)
{
	auto mysql = this->mysql();
	auto data = mysql->findData(INVENTORYTABLENAME, "type", "`name`=?", {name});
	if(data.isEmpty())
		return QString();
	return data.begin()->toString();
}

quint64 MainModel::currentInventory(const QString& name)
{
	auto mysql = this->mysql();
	auto data = mysql->findData(INVENTORYTABLENAME, "currentInventory", "`name`=?", { name });
	if (data.isEmpty())
		return quint64(0);
	return data.begin()->toULongLong();
	
}

InventoryModel MainModel::inventory(const QString& name)
{
	auto mysql = this->mysql();
	auto data = mysql->findDatas_toMap(INVENTORYTABLENAME, InventoryModel().fields(), "`name`=?", { name });
	if (data.isEmpty())
		return InventoryModel();
	return InventoryModel(*data.begin());
}

quint64 MainModel::newProductIDMySql()
{
	auto mysql = this->mysql();
	mysql->Query(QString("SHOW TABLE STATUS LIKE  '%1'").arg(PRODUCTTABLENAME));
	//QVariantList data;
	return mysql->result_all()[0][10].toULongLong();
}

bool MainModel::addProductMySql(const ProductModel& product, ProductModel* newProduct)
{
	auto mysql = this->mysql();
	if (mysql->findData(PRODUCTTABLENAME, "product_id", "`name`=?", { product.name() }).isEmpty())
	{
		auto fields = product.fields();
		if (mysql->INSERT(PRODUCTTABLENAME, product.toMap(fields)))
		{
			return true;
		}

	}

	return false;
}

bool MainModel::modifyProductMySql(const ProductModel& product)
{
	auto mysql = this->mysql();
	if (!mysql->findData(PRODUCTTABLENAME, "name", "`product_id`=?", { product.product_id() }).isEmpty())
	{
		auto p = product;
		p.setMTime();
		if (mysql->UPDATE(PRODUCTTABLENAME, p.toMap(p.fields()), "`product_id`=?", { product.product_id() }))
		{
			return true;
		}
	}
	return false;
}

bool MainModel::removeProductMySql(const ProductModel& product)
{
	auto mysql = this->mysql();
	if (!mysql->findData(PRODUCTTABLENAME, "name", "`id`=?", { QString("%1").arg(product.product_id()) }).isEmpty())
	{
		if (mysql->DELETE(PRODUCTTABLENAME, "`id`=?", { QString("%1").arg(product.product_id()) }))
		{
			return true;
		}
	}
	return false;
}

QList<ProductModel> MainModel::ProductListMySql()
{
	QList<ProductModel> list;
	auto mysql = this->mysql();
	;
	for (auto& data : mysql->findDataAll_toMap(PRODUCTTABLENAME))
	{
		list << ProductModel(data);
	}
	return list;
}

quint64 MainModel::currentProductNumber(const QString& name)
{
	auto mysql = this->mysql();
	auto data = mysql->findData(PRODUCTTABLENAME, "number", "`name`=?", { name });
	if (data.isEmpty())
		return quint64(0);
	return data.begin()->toULongLong();
}

ProductModel MainModel::product(const QString& name)
{
	auto mysql = this->mysql();
	auto data = mysql->findDatas_toMap(PRODUCTTABLENAME, ProductModel().fields(), "`name`=?", {name});
	if (data.isEmpty())
		return ProductModel();
	return ProductModel(*data.begin());
}

quint64 MainModel::newOrderIDMySql()
{
	auto mysql = this->mysql();
	mysql->Query(QString("SHOW TABLE STATUS LIKE  '%1'").arg(ORDERTABLENAME));
	//QVariantList data;
	return mysql->result_all()[0][10].toULongLong();
}

bool MainModel::addOrderMySql(const ProductModel& product, OrderModel* newOrder)
{
	OrderModel Order = product;
	Order.setOrder_id(newOrderIDMySql());
	Order.setAccount(userInfo()->account());
	auto mysql = this->mysql();
	if (mysql->INSERT(ORDERTABLENAME, Order.fields(), &Order))
	{
		auto productMysql = this->product(product.name());
		productMysql.setNumber(productMysql.number()- product.number());
		productMysql.setMTime();
		if (!mysql->UPDATE(PRODUCTTABLENAME, productMysql.fields(), &productMysql, "`name`=?", { product.name()}))
		{
			return false;
		}
		auto Inventory = this->inventory(product.name());
		Inventory.setCurrentInventory(Inventory.currentInventory() - product.number());
		Inventory.setRestockingQuantity(Inventory.currentInventory()< Inventory.safetyInventory()? Inventory.safetyInventory()- Inventory.currentInventory():0);
		Inventory.setMTime();
		if (!mysql->UPDATE(INVENTORYTABLENAME, Inventory.fields(), &Inventory, "`name`=?", { product.name() }))
		{
			return false;
		}

		if (newOrder)
			*newOrder = Order;
		return true;
	}
	return false;
}

QList<OrderModel> MainModel::OrderListMySql(const QString& account)
{
	QList<OrderModel> list;
	auto mysql = this->mysql();
	if (account.isEmpty())
	{
		for (auto& data : mysql->findDataAll_toMap(ORDERTABLENAME))
		{
			list << OrderModel(data);
		}
	}
	else
	{
		for (auto& data : mysql->findDatas_toMap(ORDERTABLENAME, OrderModel().fields(), "`account`=?",{account}))
		{
			list << OrderModel(data);
		}
	}
	
	return list;
}

void MainModel::initDatabaseTable()
{
	auto mysql = this->mysql();
	//qDebug() << "初始化表";
	/*qInfo() << "查询表是否存在,不存在将创建";*/
	//QString tableName = "User";
	if (!mysql->tabelExists(INVENTORYTABLENAME))
	{
		if (!mysql->createTable(InventoryModel(), INVENTORYTABLENAME))
		{//创建表失败

		}
	}
	if (!mysql->tabelExists(PRODUCTTABLENAME))
	{
		if (!mysql->createTable(ProductModel(), PRODUCTTABLENAME))
		{//创建表失败

		}
	}
	if (!mysql->tabelExists(ORDERTABLENAME))
	{
		if (!mysql->createTable(OrderModel(), ORDERTABLENAME))
		{//创建表失败

		}
	}
}
